package main

import (
	"errors"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	//"github.com/spf13/viper"
	"time"
)

const TokenExpireDuration = time.Hour * 2

// 定义Secret
var mySecret = []byte("夏天夏天悄悄过去")

// 自定义声明结构体MyClaims，并内嵌jwt.StandardClaims
// jwt包自带的jwt.StandardClaims只包含了官方字段
// 额外记录username，userid字段，如果需要保存更多信息，都可以添加到这个结构体中
type MyClaims struct {
	UserID   int64  `json:"user_id"`
	Username string `json:"username"`
	jwt.StandardClaims
}

// 2. 生成JWT
func GenToken(userID int64, username string) (string, error) {
	//创建一个自己声明的数据
	c := MyClaims{
		UserID:   userID,
		Username: username,
		StandardClaims: jwt.StandardClaims{
			//ExpiresAt: time.Now().Add(time.Duration(viper.GetInt("auth.jwt_expire"))).Unix(), //过期时间
			ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), //过期时间

			Issuer: "bluebell_qimi", //签发人
		},
	}
	//使用指定的签名方法创建签名对象
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	//使用指定的secret签名并获得完整的编码后的字符串token
	return token.SignedString(mySecret)
}

// 3. 解析JWT
func ParseToken(tokenString string) (*MyClaims, error) {
	//解析token
	var mc = new(MyClaims)
	token, err := jwt.ParseWithClaims(tokenString, mc, func(token *jwt.Token) (interface{}, error) {
		return mySecret, nil
	})
	if err != nil {
		return nil, err
	}
	if token.Valid {
		//校验Token
		return mc, nil
	}
	return nil, errors.New("invalid token")
}

func main() {
	fmt.Println("生成")
	data, err := GenToken(1, "yxx")
	if err != nil {
		fmt.Printf("gentoken failed err:%#v\n", err)
	}
	fmt.Println("生成的dataToken:", data)

	fmt.Println()
	fmt.Println("解析")
	mc1, mc2 := new(MyClaims), new(MyClaims)
	mc1, _ = ParseToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJ1c2Vybm\nFtZSI6Inl4eCIsImV4cCI6MTcxMjgzMzQyMCwiaXNzIjoiYmx1ZWJlbGxfcWltaSJ9.fowlCeaJ-BphV\nC-Ys9NWRYR47-PAL5Q1_Ivg7CtVGiA\n")
	fmt.Printf("mc1:%#v", mc1)
	fmt.Println()
	mc2, _ = ParseToken(data)
	fmt.Printf("mc2:%#v", mc2)

	if mc1 == mc2 {
		fmt.Println("sucess!!")
	} else {
		fmt.Println("failed!")
	}
}
